From ec1091e9ee44b2e676a8aa774b03226aa1ffaf78 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 6 Oct 2014 11:27:16 -0700 Subject: [PATCH] Remove the notion of "primary" from Context Now that we have selective testing, this no longer makes any sense and all queries to the path layout need to be based on the package being queried for. This removes the primary flag from the Context, and requires that the `layout` method have a local Package available cc servo/servo#3580 --- src/cargo/ops/cargo_rustc/context.rs | 21 +++++------ src/cargo/ops/cargo_rustc/fingerprint.rs | 10 +++--- src/cargo/ops/cargo_rustc/mod.rs | 45 ++++++++---------------- tests/test_cargo_test.rs | 28 +++++++++++++++ 4 files changed, 56 insertions(+), 48 deletions(-) diff --git a/src/cargo/ops/cargo_rustc/context.rs b/src/cargo/ops/cargo_rustc/context.rs index cba02feff..8f5d1d3ca 100644 --- a/src/cargo/ops/cargo_rustc/context.rs +++ b/src/cargo/ops/cargo_rustc/context.rs @@ -17,7 +17,6 @@ pub enum PlatformRequirement { } pub struct Context<'a, 'b> { - pub primary: bool, pub rustc_version: String, pub config: &'b mut Config<'b>, pub resolve: &'a Resolve, @@ -59,7 +58,6 @@ impl<'a, 'b> Context<'a, 'b> { env: env, host: host, target: target, - primary: false, resolve: resolve, sources: sources, package_set: deps, @@ -155,8 +153,10 @@ impl<'a, 'b> Context<'a, 'b> { self.compilation.extra_env.insert("NUM_JOBS".to_string(), Some(self.config.jobs().to_string())); - self.compilation.root_output = self.layout(KindTarget).proxy().dest().clone(); - self.compilation.deps_output = self.layout(KindTarget).proxy().deps().clone(); + self.compilation.root_output = + self.layout(pkg, KindTarget).proxy().dest().clone(); + self.compilation.deps_output = + self.layout(pkg, KindTarget).proxy().deps().clone(); return Ok(()); } @@ -186,19 +186,14 @@ impl<'a, 'b> Context<'a, 'b> { .map(|a| *a).unwrap_or(PlatformTarget) } - /// Switch this context over to being the primary compilation unit, - /// affecting the output of `dest()` and such. - pub fn primary(&mut self) { - self.primary = true; - } - /// Returns the appropriate directory layout for either a plugin or not. - pub fn layout(&self, kind: Kind) -> LayoutProxy { + pub fn layout(&self, pkg: &Package, kind: Kind) -> LayoutProxy { + let primary = pkg.get_package_id() == self.resolve.root(); match kind { - KindPlugin => LayoutProxy::new(&self.host, self.primary), + KindPlugin => LayoutProxy::new(&self.host, primary), KindTarget => LayoutProxy::new(self.target.as_ref() .unwrap_or(&self.host), - self.primary) + primary) } } diff --git a/src/cargo/ops/cargo_rustc/fingerprint.rs b/src/cargo/ops/cargo_rustc/fingerprint.rs index f1840da87..7af5995b8 100644 --- a/src/cargo/ops/cargo_rustc/fingerprint.rs +++ b/src/cargo/ops/cargo_rustc/fingerprint.rs @@ -82,7 +82,7 @@ pub fn prepare_target(cx: &mut Context, pkg: &Package, target: &Target, let is_rustc_fresh = try!(is_fresh(&old_loc, rustc_fingerprint.as_slice())); let (old_root, root) = { - let layout = cx.layout(kind); + let layout = cx.layout(pkg, kind); (layout.old_root().clone(), layout.root().clone()) }; let mut pairs = vec![(old_loc, new_loc.clone())]; @@ -151,10 +151,10 @@ pub fn prepare_build_cmd(cx: &mut Context, pkg: &Package) let is_fresh = try!(is_fresh(&old_loc, new_fingerprint.as_slice())); let pairs = vec![(old_loc, new_loc.clone()), - (cx.layout(kind).old_native(pkg), - cx.layout(kind).native(pkg))]; + (cx.layout(pkg, kind).old_native(pkg), + cx.layout(pkg, kind).native(pkg))]; - let native_dir = cx.layout(kind).native(pkg); + let native_dir = cx.layout(pkg, kind).native(pkg); cx.compilation.native_dirs.insert(pkg.get_package_id().clone(), native_dir); Ok(prepare(is_fresh, new_loc, new_fingerprint, pairs)) @@ -193,7 +193,7 @@ fn prepare(is_fresh: bool, loc: Path, fingerprint: String, /// Return the (old, new) location for fingerprints for a package pub fn dirs(cx: &Context, pkg: &Package, kind: Kind) -> (Path, Path) { - let layout = cx.layout(kind); + let layout = cx.layout(pkg, kind); let layout = layout.proxy(); (layout.old_fingerprint(pkg), layout.fingerprint(pkg)) } diff --git a/src/cargo/ops/cargo_rustc/mod.rs b/src/cargo/ops/cargo_rustc/mod.rs index 4260ab34f..f1428c57e 100644 --- a/src/cargo/ops/cargo_rustc/mod.rs +++ b/src/cargo/ops/cargo_rustc/mod.rs @@ -97,9 +97,6 @@ pub fn compile_targets<'a>(env: &str, targets: &[&'a Target], pkg: &'a Package, try!(compile(targets.as_slice(), dep, compiled, &mut cx, &mut queue)); } - if pkg.get_package_id() == resolve.root() { - cx.primary(); - } try!(compile(targets, pkg, true, &mut cx, &mut queue)); // Now that we've figured out everything that we're going to do, do it! @@ -205,7 +202,7 @@ fn compile_custom(pkg: &Package, cmd: &str, let mut cmd = cmd.split(' '); // TODO: this shouldn't explicitly pass `KindTarget` for dest/deps_dir, we // may be building a C lib for a plugin - let layout = cx.layout(KindTarget); + let layout = cx.layout(pkg, KindTarget); let output = layout.native(pkg); let old_output = layout.proxy().old_native(pkg); let mut p = process(cmd.next().unwrap(), pkg, cx) @@ -253,18 +250,14 @@ fn rustc(package: &Package, target: &Target, cx: &mut Context, req: PlatformRequirement) -> CargoResult >{ let crate_types = target.rustc_crate_types(); - let root = package.get_root(); - - log!(5, "root={}; target={}; crate_types={}; verbose={}; req={}", - root.display(), target, crate_types, cx.primary, req); - let rustcs = try!(prepare_rustc(package, target, crate_types, cx, req)); Ok(rustcs.into_iter().map(|(rustc, kind)| { let name = package.get_name().to_string(); let desc = rustc.to_string(); let is_path_source = package.get_package_id().get_source_id().is_path(); - let show_warnings = cx.primary || is_path_source; + let show_warnings = package.get_package_id() == cx.resolve.root() || + is_path_source; let rustc = if show_warnings {rustc} else {rustc.arg("-Awarnings")}; (proc() { @@ -304,7 +297,7 @@ fn rustdoc(package: &Package, target: &Target, cx: &mut Context) -> CargoResult<(Work, String)> { let kind = KindTarget; let pkg_root = package.get_root(); - let cx_root = cx.layout(kind).proxy().dest().join("doc"); + let cx_root = cx.layout(package, kind).proxy().dest().join("doc"); let rustdoc = process("rustdoc", package, cx).cwd(pkg_root.clone()); let rustdoc = rustdoc.arg(target.get_src_path()) .arg("-o").arg(cx_root) @@ -313,7 +306,7 @@ fn rustdoc(package: &Package, target: &Target, log!(5, "commands={}", rustdoc); - let primary = cx.primary; + let primary = package.get_package_id() == cx.resolve.root(); let name = package.get_name().to_string(); let desc = rustdoc.to_string(); Ok((proc() { @@ -408,7 +401,7 @@ fn build_base_args(cx: &Context, fn build_plugin_args(mut cmd: ProcessBuilder, cx: &Context, pkg: &Package, target: &Target, kind: Kind) -> ProcessBuilder { cmd = cmd.arg("--out-dir"); - cmd = cmd.arg(cx.layout(kind).root()); + cmd = cmd.arg(cx.layout(pkg, kind).root()); let (_, dep_info_loc) = fingerprint::dep_info_loc(cx, pkg, target, kind); cmd = cmd.arg("--dep-info").arg(dep_info_loc); @@ -436,9 +429,7 @@ fn build_plugin_args(mut cmd: ProcessBuilder, cx: &Context, pkg: &Package, fn build_deps_args(mut cmd: ProcessBuilder, target: &Target, package: &Package, cx: &Context, kind: Kind) -> CargoResult { - enum LinkReason { Dependency, LocalLib } - - let layout = cx.layout(kind); + let layout = cx.layout(package, kind); cmd = cmd.arg("-L").arg(layout.root()); cmd = cmd.arg("-L").arg(layout.deps()); @@ -455,9 +446,7 @@ fn build_deps_args(mut cmd: ProcessBuilder, target: &Target, package: &Package, } for &(pkg, target) in cx.dep_targets(package).iter() { - let pkgid = pkg.get_package_id(); - let reason = if pkgid == cx.resolve.root() {LocalLib} else {Dependency}; - cmd = try!(link_to(cmd, target, cx, kind, reason)); + cmd = try!(link_to(cmd, pkg, target, cx, kind)); } let mut targets = package.get_targets().iter().filter(|target| { @@ -470,32 +459,28 @@ fn build_deps_args(mut cmd: ProcessBuilder, target: &Target, package: &Package, continue; } - cmd = try!(link_to(cmd, target, cx, kind, LocalLib)); + cmd = try!(link_to(cmd, package, target, cx, kind)); } } return Ok(cmd); - fn link_to(mut cmd: ProcessBuilder, target: &Target, - cx: &Context, kind: Kind, - reason: LinkReason) -> CargoResult { + fn link_to(mut cmd: ProcessBuilder, pkg: &Package, target: &Target, + cx: &Context, kind: Kind) -> CargoResult { // If this target is itself a plugin *or* if it's being linked to a // plugin, then we want the plugin directory. Otherwise we want the // target directory (hence the || here). - let layout = cx.layout(match kind { + let layout = cx.layout(pkg, match kind { KindPlugin => KindPlugin, KindTarget if target.get_profile().is_plugin() => KindPlugin, KindTarget => KindTarget, - }).proxy(); + }); for filename in try!(cx.target_filenames(target)).iter() { let mut v = Vec::new(); v.push_all(target.get_name().as_bytes()); v.push(b'='); - match reason { - Dependency => v.push_all(layout.deps().as_vec()), - LocalLib => v.push_all(layout.dest().as_vec()), - } + v.push_all(layout.root().as_vec()); v.push(b'/'); v.push_all(filename.as_bytes()); cmd = cmd.arg("--extern").arg(v.as_slice()); @@ -507,7 +492,7 @@ fn build_deps_args(mut cmd: ProcessBuilder, target: &Target, package: &Package, pub fn process(cmd: T, pkg: &Package, cx: &Context) -> ProcessBuilder { // When invoking a tool, we need the *host* deps directory in the dynamic // library search path for plugins and such which have dynamic dependencies. - let layout = cx.layout(KindPlugin); + let layout = cx.layout(pkg, KindPlugin); let mut search_path = DynamicLibrary::search_path(); search_path.push(layout.deps().clone()); diff --git a/tests/test_cargo_test.rs b/tests/test_cargo_test.rs index e739f3463..07a7656db 100644 --- a/tests/test_cargo_test.rs +++ b/tests/test_cargo_test.rs @@ -1025,3 +1025,31 @@ test!(almost_cyclic_but_not_quite { assert_that(p.process(cargo_dir().join("cargo")).arg("test"), execs().with_status(0)); }) + +test!(build_then_selective_test { + let p = project("a") + .file("Cargo.toml", r#" + [package] + name = "a" + version = "0.0.1" + authors = [] + + [dependencies.b] + path = "b" + "#) + .file("src/lib.rs", "extern crate b;") + .file("src/main.rs", "extern crate b; extern crate a; fn main() {}") + .file("b/Cargo.toml", r#" + [package] + name = "b" + version = "0.0.1" + authors = [] + "#) + .file("b/src/lib.rs", ""); + + assert_that(p.cargo_process("build"), execs().with_status(0)); + p.root().move_into_the_past().unwrap(); + assert_that(p.process(cargo_dir().join("cargo")).arg("test") + .arg("-p").arg("b"), + execs().with_status(0)); +}) -- 2.30.2